﻿/**

 @Name：swui.live2d 看板娘模块
 @Author：Zxq
 @License：MIT
    
 */

layui.define(['jquery', 'swui'], function (exports) {
    "use strict";

    var $ = layui.jquery,userActionTimer,msgPriority,msgTimer;

    //助手构造函数
    var Live2d = function () {
        swui.baseObject.call(this, 'live2d');
        this.helps = {};
        this.Mode = 'normal';
        this.ModelList = [
            {name: 'Pio', themes: ['Potion-Maker/Pio'], message: '来自 Potion Maker 的 Pio 酱 ~'},
            {name: 'Tia', themes: ['Potion-Maker/Tia'], message: '来自 Potion Maker 的 Tia 酱 ~'},
            {name: '22', themes: ['bilibili-live/22'], message: '来自 Bilibili Live 的 22 哦 ~'},
            {name: '33', themes: ['bilibili-live/33'], message: '来自 Bilibili Live 的 33 的说'},
            {name: 'shizuku', themes: ['ShizukuTalk/shizuku-48', 'ShizukuTalk/shizuku-pajama'], message: 'Shizuku Talk ！这里是 Shizuku ~'},
            {name: 'Neptunia', themes: [
                    'HyperdimensionNeptunia/neptune_classic',
                    'HyperdimensionNeptunia/nepnep',
                    'HyperdimensionNeptunia/neptune_santa',
                    'HyperdimensionNeptunia/nepmaid',
                    'HyperdimensionNeptunia/nepswim',
                    'HyperdimensionNeptunia/noir_classic',
                    'HyperdimensionNeptunia/noir',
                    'HyperdimensionNeptunia/noir_santa',
                    'HyperdimensionNeptunia/noireswim',
                    'HyperdimensionNeptunia/blanc_classic',
                    'HyperdimensionNeptunia/blanc_normal',
                    'HyperdimensionNeptunia/blanc_swimwear',
                    'HyperdimensionNeptunia/vert_classic',
                    'HyperdimensionNeptunia/vert_normal',
                    'HyperdimensionNeptunia/vert_swimwear',
                    'HyperdimensionNeptunia/nepgear',
                    'HyperdimensionNeptunia/nepgear_extra',
                    'HyperdimensionNeptunia/nepgearswim',
                    'HyperdimensionNeptunia/histoire',
                    'HyperdimensionNeptunia/histoirenohover'
                ], message: 'Nep! Nep! 超次元游戏：海王星 系列'},
            {name: 'murakumo', themes: ['KantaiCollection/murakumo'], message: '艦隊これくしょん / 叢雲(むらくも)'}
        ];
        this.messageArray = ["好久不见，日子过得好快呢……", "大坏蛋！你都多久没理人家了呀，嘤嘤嘤～", "嗨～快来逗我玩吧！", "拿小拳拳锤你胸口！", "记得把小家加入 Adblock 白名单哦！"];
    };

    //默认配置
    Live2d.prototype = {
        //初始化html元素及事件
        render: function (callback) {
            if (this.configs.close === true) {
                this.configs.close = false;
            }
            else {
                var othis = this;
                if (!othis.configs.container) return;
                var html = ['<div id="live2d-main">',
			'<div id="live2d-tips"></div>',
			'<canvas id="live2dcanvas" width="200px" height="200px"></canvas>',
			'<div id="live2d-tool">',
			'</div>',
        '</div>'].join('');
                othis.elem = $(html).appendTo(swui.elems.body);
                othis.msgbox = othis.elem.find('#live2d-tips');
                othis.tool = othis.elem.find('#live2d-tool');
                layui.link(swui.path + 'css/live2d.css', 'live2d');
                setTimeout(function(){othis.elem.removeClass(othis.cssName.HIDE);},100);

                othis.setData({urlcode:'uihelper'}, function (data) {
                    othis.data = data;
                    othis.renderElems();
                }, false);
            }
            //调用渲染完毕的回调函数
            if (this.Utils.isFunction(callback))
                callback.call(this);
        }
        ,renderElems: function () {
            //if (this.data === null) return;
            if (this.data.msg)
                this.msgbox.html(this.data.msg);
            else this.hideMessage();
            var html = ['<span class="fa fa-comment"></span>',
				'<span class="fa fa-paper-plane" data-help="要不要来玩飞机大战？"></span>',
				'<span class="fa fa-user-circle"></span>',
				'<span class="fa fa-street-view"></span>',
				'<span class="fa fa-camera-retro"></span>',
				'<span class="fa fa-info-circle"></span>',
                '<span class="fa fa-times"></span>'].join('');
            this.tool.append(html);
            if (this.data.menus) {
                var othis = this;
                $(this.data.menus).each(function (index, item) {
                    //othis.tool.append('<span class="fa fa-lg fa-comment"></span>');
                });
            }
            
            othis.resetEvents();
        }
        ,resetEvents: function () {
            var othis = this;
            var modelUrl="./swuiadmin/live2d/assets/22.2018.lover/22.2018.lover.model.json";
            loadlive2d("live2dcanvas", modelUrl);
            this.kid = drag.init(othis.elem[0],{container:othis.configs.container,afterMove:function(){othis.locaMsgBox()}});
            setInterval(function() {
                if (new Date().getTime() - swui.lastActionTime < 20000) {
                    clearInterval(userActionTimer);
                    userActionTimer = null;
                } else if (!userActionTimer) {
                    userActionTimer = setInterval(function() {
                        othis.showAutoMessage({message: othis.messageArray});
                    }, 20000);
                }
            }, 1000);
            othis.resetEvent('click', this.elem, function(e){
                if (othis.Mode === 'guide' || othis.Mode === 'menu') return;
                else if (othis.Mode === 'run') {//瞎跑模式
                    var p = {},o = $(othis.configs.container).offset();
                    var l = $(othis.configs.container).outerWidth()-othis.elem.outerWidth();
                    var t = $(othis.configs.container).outerHeight()-othis.elem.outerHeight();
                    p.left = o.left+Math.floor(Math.random() * l);
                    p.top = o.top+Math.floor(Math.random() * t);
                    othis.moveTo(p, function(){othis.showAutoMessage('点我就瞎跑');});
                }
                else {
                    var d = othis.data.msgs;
                    var msg = d[Math.floor(Math.random() * d.length)];
                    othis.showAutoMessage(msg);
                }
            }, null, false);
            othis.resetEvent('dblclick', this.elem, function(e){
                if (othis.Mode === 'guide' || othis.Mode === 'menu') return;
                othis.showAutoMessage('双击开启瞎跑模式');
                othis.setMode('run');
                othis.kid.setMoveAble(false);
            },null, false);
            othis.resetEvent('contextmenu', this.elem, function(e){
                if (othis.Mode === 'guide') return;
                else if (othis.Mode === 'run') {
                    othis.setMode('normal');
                    othis.showAutoMessage('跑累了，休息一下吧，来开始教学吧');
                    othis.guideMode([{elem:'.swui-desktop-item[data-code="theme"]',tip:'这是主题',event:'dblclick'}
                                    ,{elem:'.swui-desktop-item[data-code="auth"]',tip:'这是作者',prev:true}
                                    ,{elem:'.swui-desktop-item[data-code="remark"]',tip:'这是基本说明',prev:true,event:'dblclick'}
                                    ,{elem:'.swui-desktop-item[data-code="sysmenu"]',tip:'这是系统菜单',prev:true,exit:true}
                                    ,{elem:'.swui-desktop-item[data-code="role"]',tip:'这是角色管理',prev:true,exit:true,event:'dblclick'}
                                    ,{elem:'.swui-desktop',tip:'这是桌面',prev:true,exit:true}
                                    ,{elem:'.swui-taskbar-start',tip:'这是菜单列表',prev:true,exit:true}
                                    ,{elem:'.swui-taskbar-desktop',tip:'这是显示隐藏桌面',prev:true,exit:true}
                                    ,{elem:'.swui-taskbar-helper',tip:'我在这里，点击就可以隐藏或显示我',prev:true,exit:true}]);
                }
            },null, false);
            //看板娘功能项
            othis.resetEvent('click mousedown','span', function(e){
                //var item = othis.configs.events[$(this).data('code')];
                //if (item && othis.Utils.isFunction(item.handler)) {
                //    item.handler.call(this);
                //}
                othis.sp(e);
            },othis.tool);
            othis.resetEvent('mouseenter', this.msgbox, function(e){
                if (msgTimer) {
                    clearTimeout(msgTimer);
                    msgTimer = null;
                }
            });
            othis.resetEvent('mouseleave', this.msgbox, function(e){
                if (othis.Mode === 'guide') return;
                msgTimer = setTimeout(function (){ othis.hideMessage(); }, 3000);
            });
            //消息框内的按钮事件
            othis.resetEvent('click', '.live2d-guide-operate a', function(e){
                if (!othis.msgbox.buttons) return;
                var btn = othis.msgbox.buttons[$(this).index()];
                if (!btn || !othis.Utils.isFunction(btn.handler)) return;
                if (btn.hide) othis.hideMessage();
                btn.handler.call(this, e);
            },othis.msgbox);
        }
        //自适应大小事件
        ,resizeEvent: function (e) {
            this.locaLive();
            if (this.Mode === 'guide') {
                var othis = this;
                this.guideToElem(function(){othis.locaMsgBox();});
            }
        }
        ,randomSelection: function (obj) {
            return Array.isArray(obj) ? obj[Math.floor(Math.random() * obj.length)] : obj;
        }
        //改变模式：normal/guide/run/menu
        ,setMode: function (mode) {
            if (this.Mode === mode) return;
            switch (mode) {
                case 'guide':
                    this.elem.addClass('guideMode');
                    this.kid.setMoveAble(false);
                    break;
                case 'run':
                    this.elem.removeClass('guideMode');
                    this.kid.setMoveAble(false);
                    break;
                default:
                    this.elem.removeClass('guideMode');
                    this.kid.setMoveAble(true);
                    break;
            }
            this.Mode = mode;
        }
        //看板娘移动函数(动画)
        ,moveTo: function (pos, callback) {
            var othis = this;
            this.elem.animate(pos, {
                duration: 500,
                complete: function(){
                    if (othis.Utils.isFunction(callback))
                        callback.call(this);
                }
                //progress: function(animation, progress) {
                    //console.log(Math.round(progress * 100));
                //   if (progress === 1) callback.call(this);
                //}
            });
        }
        //显示看板娘
        ,show: function () {
            if (othis.configs.anima)
                this.elem.removeClass('off').addClass('on');
            else this.elem.removeClass(this.cssName.HIDE);
        }
        //隐藏看板娘
        ,hide: function () {
            if (othis.configs.anima)
                this.elem.removeClass('on').addClass('off');
            else this.elem.addClass(this.cssName.HIDE);
        }
        ,open: function (callback) {
            if (this.elem && this.elem.length > 0) return;
            this.render(callback);
        }
        //关闭看板娘
        ,close: function () {
            this.elem.remove();
            this.setMode('normal');
        }
        //定位看板娘
        ,locaLive: function () {
            var parentElem = $(this.configs.container);
            var bubble = this.elem;
            if (!bubble || bubble.length === 0) return;
            var ppos = parentElem.offset();
            var bpos = bubble.offset();
            var pos = {};
            if (bubble.outerWidth()+bpos.left > parentElem.outerWidth()+ppos.left)
                pos.left = parentElem.outerWidth()+ppos.left-bubble.outerWidth();
            else if (bpos.left < ppos.left)
                pos.left = ppos.left;
            if (bubble.outerHeight()+bpos.top > parentElem.outerHeight()+ppos.top)
                pos.top = parentElem.outerHeight()+ppos.top-bubble.outerHeight();
            else if (bpos.top < ppos.top)
                pos.top = ppos.top;
            this.elem.css(pos);
        }
        //定位消息框
        ,locaMsgBox:function(){
            var bubble = this.elem;
            if (!bubble || bubble.length === 0) return;
            var bpos = bubble.offset();
            var mTop = bpos.top;
            if (mTop < 30)
                mTop *=-1;
            else if (mTop > 30)
                mTop = -30;
            this.msgbox.css('margin-top', mTop + 'px');
        }
        //显示消息 
        ,showMessage: function (option) {
            if (!this.elem || this.elem.css("display") == 'none')
                return;
            var message, timeout, priority;
            if (this.Utils.isString(option)) {
                message = option;
                timeout = 0;
                priority = 0;
            }
            else {
                message = option.message;
                timeout = option.timeout || 0;
                priority = option.priority || 0;
            }
            if (!message || msgPriority > priority) 
                return;
            if (msgTimer) {
                clearTimeout(msgTimer);
                msgTimer = null;
            }
            this.msgbox.buttons = option.buttons;
            if (option.buttons && option.buttons.length > 0) {
                message += '<div class="live2d-guide-operate">';
                $.each(option.buttons, function(index, btn){
                    message += '<a href="javascript:void(0);">'+btn.name+'</a>';
                });
                message += '</div>';
            }
            message = this.randomSelection(message);
            this.msgbox.html(message).addClass('live2d-tips-active');
            this.locaMsgBox();
            if (timeout > 0) {
                var othis = this;
                msgTimer = setTimeout(function() { othis.hideMessage(); }, timeout);
            }
        }
        //隐藏消息 
        ,hideMessage: function () {
            if (this.msgbox) {
                this.msgPriority = 0;
                this.msgbox.removeClass('live2d-tips-active');
            }
        }
        //显示消息自动隐藏 
        ,showAutoMessage: function (option) {
            if (this.Utils.isString(option)){
                option = {message:option,timeout:5000};
            }
            else if (this.Utils.isObject(option)) {
                !option.timeout && (option.timeout = 5000);
            }
            else return;
            this.showMessage(option);
        }
        //向导指引模式
        ,guideMode: function (objs) {
            this.setMode('guide');
            var othis = this;
            //var shade = $('<canvas id="canvasId" class="live2d-guide"></canvas>').appendTo('body');
            var shade = $('<div class="live2d-guide"><div class="live2d-guide-top"></div><div class="live2d-guide-left"></div><div class="live2d-guide-body"></div><div class="live2d-guide-right"></div><div class="live2d-guide-bottom"></div></div>').appendTo('body');

            var i = -1;
            this.resetEvent('click', shade, function(e){
                e=e||window.event;
                if ($(e.target||e.srcElement).is('.live2d-guide-body')&&objs[i].event) return false;
                i++;
                //结束向导模式
                if (i === objs.length) {
                    guideEnd();
                    return;
                }
                var ind = i;//移动小助手的动画有延迟，为避免延迟后i值已变成objs.length而导致后面报错，因此用ind替换i
                othis.guideElem = $(objs[ind].elem);
                var msg = objs[ind].tip;
                var btns = [];
                if (objs[ind].exit) {
                    btns.push({name:'退出向导',handler:function(e){ guideEnd(); othis.sp(e); }});
                }
                if (objs[ind].prev) {
                    btns.push({name:'上一步',handler:function(e){ i -= 2; shade.trigger('click'); }});
                }
                othis.guideToElem(function(){
                    if (objs[ind].event) {
                        othis.resetEvent(objs[ind].event, '.live2d-guide-body', function(){
                            $(this).off(objs[ind].event);
                            othis.guideElem.trigger(objs[ind].event);
                        },shade);
                    }
                    othis.showMessage({message:msg,buttons:btns});
                });
                othis.sp(e);
            });
            var guideEnd = function(){
                othis.setMode('normal');
                shade.remove();
                othis.hideMessage();
            }
            shade.trigger('click');
        }
        //指引到某个元素旁边
        ,guideToElem: function ($item,callback) {
            if (this.Utils.isFunction($item) && !callback){
                callback = $item;
                $item = null;
            }
            !$item && ($item = this.guideElem);
            if ($item.length === 0 || $item.is(':hidden')) return;
            var p = $item.offset();
            var shade = $('.live2d-guide');
            p.width = $item.outerWidth();
            p.height = $item.outerHeight();
            if (shade.length > 0) {//向导模式锁屏点击指引元素
                shade.children('.live2d-guide-top').css({height:p.top});
                shade.children('.live2d-guide-bottom').css({top:p.top+p.height});
                shade.children('.live2d-guide-left').css({marginTop:p.top,height:p.height,width:p.left});
                shade.children('.live2d-guide-right').css({marginTop:p.top,left:p.left+p.width,height:p.height});
                shade.children('.live2d-guide-body').css(p);
                //var canvas = document.getElementById("canvasId");
                //var context = canvas.getContext("2d");
                //context.clearRect(p.left,p.top,p.width,p.height);//抠出一个矩形区域
            }
            var t = p.top - (this.elem.outerHeight()-p.height) / 2;
            var l = p.left+p.width;
            if (l+this.elem.outerWidth()>$(document).width()) {
                l = p.left-this.elem.outerWidth();
                if (l < 0) {//放至目标元素中间区域
                    l = p.left + (p.width - this.elem.outerWidth()) / 2;
                }
            }
            if (t+this.elem.outerHeight()>$(document).height()) {
                t = p.top-this.elem.outerHeight();
                if (t < 0) {//放至目标元素中间区域
                    t = p.top + (p.height - this.elem.outerHeight()) / 2;
                }
                else {//放到正上方
                    l = p.left - (this.elem.outerWidth()-p.width) / 2;
                    if (l+this.elem.outerWidth()>$(document).width())
                        l = $(document).width()-this.elem.outerWidth();
                    else if (l<0)
                        l = 0;
                }
            }
            //定位小助手
            this.moveTo({left:l,top:t<0?0:t},callback);
        }
    };

    var live2d = new Live2d();

    swui.live2d = live2d;

    exports(live2d.MOD_NAME, {});

    delete layui.live2d;
});